package android_testsuite.mytest.network_test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.lang.ref.WeakReference;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.Date;

import android.util.Log;

import android_testsuite.mytest.util.Const;

/**
 * @author Ren Hui
 * @since 1.0.1.058
 */
public class TcpRunnable implements Runnable {
    //IP地址
    private String mIp;
    // 一次发送的数据流的大小
    private int mLength = 1024;
    // 发送时间
    private Date mSenDate;
    // 接收时间
    private Date mRecDate;
    // 延时总和
    private long mSum = 0;
    // 延时平均
    private double mAverage = 0;
    //收发正确时间
    private int mRightTimes = 0;
    private WeakReference<SocketActivity> mActivityWeakReference;

    public TcpRunnable(SocketActivity activity, String ip, int length) {
        super();
        this.mIp = ip;
        this.mLength = length;
        this.mActivityWeakReference = new WeakReference<SocketActivity>(activity);
    }

    @Override
    public void run() {
        TcpFun tcpConnect = new TcpFun();
        tcpConnect.func();
    }

    private class TcpFun {
        private Socket mSocket = null;
        // 输出流
        private PrintStream mOutStream = null;
        // 输入流
        private BufferedReader mInStream = null;

        public TcpFun() {
            mSocket = new Socket();
            // 设置参数
            try {
                mSocket.setSoTimeout(Const.SO_TIMEOUT);
            } catch (SocketException e) {
                e.printStackTrace();
            }
        }

        private boolean connect() {
            try {
                // 定义要链接的地址和端口
                SocketAddress address = new InetSocketAddress(mIp, Const.ECHO_PORT);
                mSocket.connect(address,Const.CONNECTION_TIMEOUT);
                return true;
            } catch (SocketTimeoutException e) {
                showLogMsg(e.toString()+"\n");
                return false;
            } catch (IOException e) {
                showLogMsg(e.toString() + "\n");
                return false;
            }
        }

        private void send() throws IOException {
            char[] ch = new char[mLength];
            String str = new String(ch);
            mOutStream = new PrintStream(mSocket.getOutputStream());
            mOutStream.println(str);
            mSenDate = new Date();
        }

        private void receive()  throws IOException {
            mInStream = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            String echo = mInStream.readLine();
            Log.d("TcpRunnable", echo);
            mRecDate = new Date();
        }

        public void close() {
            if (mOutStream != null) {
                // 关闭流
                mOutStream.close();
            }

            try {
                if (mInStream != null) {
                    mInStream.close();
                }
            } catch (IOException e) {
                showLogMsg(e.toString() + "\n");
            }

            // 关闭socket
            try {
                if(!mSocket.isClosed()) {
                    mSocket.close();
                }
            } catch (IOException e) {
                showLogMsg(e.toString() + "\n");
            }
        }

        public void func() {
            //如果连接主机失败，直接返回
            if(!connect()) {
                close();
                return ;
            }

            for (int i = 0; i < Const.SEND_TIMES; i++) {
                try {
                    send();
                    receive();
                } catch (IOException e) {
                    showLogMsg(e.toString()+"\n");
                    continue;
                }

               if (mRecDate != null && mSenDate != null) {
                    long dif = mRecDate.getTime() - mSenDate.getTime();
                    mSum += dif;
                    //记录成功收发次数
                    mRightTimes++;
                }
            }

            if (mRightTimes != 0) {
                mAverage = (double) mSum / mRightTimes;
                //延时取往返时间的一半
                mAverage /= 2;
                showLogMsg("时延" + mAverage + "ms.\n");
            } else {
                showLogMsg("网络异常\n");
            }
            close();
        }

        // 显示信息
        public void showLogMsg(String msg) {
            final SocketActivity activity = mActivityWeakReference.get();
            if (activity != null) {
                activity.onLogging(msg);
            } else {
                return;
            }
        }
    }
}
